package com.jztd.platfrom.base.interceptor;

import com.jztd.platfrom.base.annotation.UnifiedResponseBody;
import com.jztd.platfrom.base.model.Result;
import com.jztd.platfrom.base.util.HttpUtils;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;

import java.util.Objects;

/**
 * 响应结果统一包装拦截器，默认不包装
 * @author lj
 * @date 2025/08/03
 */
public class UnifiedResponseInterceptor implements HandlerMethodReturnValueHandler {
    private final RequestResponseBodyMethodProcessor processor;

    public UnifiedResponseInterceptor(RequestResponseBodyMethodProcessor processor) {
        this.processor = processor;
    }

    /**
     * 判断目标方法是否使用@ResponseBody注解
     *
     * @param method 目标方法参数对象
     * @return true/false
     */
    private boolean isResponseBodyMethod(MethodParameter method) {
        return method.hasMethodAnnotation(ResponseBody.class)
                || method.getDeclaringClass().isAnnotationPresent(ResponseBody.class)
                || method.getDeclaringClass().isAnnotationPresent(RestController.class);
    }

    /**
     * 判断目标方法是否使用{@link UnifiedResponseBody}
     *
     * @param method 目标方法参数对象
     * @return true/false
     */
    private boolean isUnifiedResponseMethod(MethodParameter method) {
        UnifiedResponseBody unified = method.getMethodAnnotation(UnifiedResponseBody.class);
        if (unified == null) {
            unified = method.getDeclaringClass().getAnnotation(UnifiedResponseBody.class);
        }
        return unified != null && unified.value();
    }

    @Override
    public boolean supportsReturnType(MethodParameter method) {
        return this.isResponseBodyMethod(method) && this.isUnifiedResponseMethod(method);
    }

    @Override
    public void handleReturnValue(Object value, MethodParameter method, ModelAndViewContainer container,
                                  NativeWebRequest request) throws Exception {
        // 如果接口方法返回类型是void，则将请求结果data设置OK
        if (Objects.requireNonNull(method.getMethod()).getReturnType() == void.class) {
            value = HttpStatus.OK.name();
        }

        // 处理返回值
        HttpServletResponse response = Objects.requireNonNull(request.getNativeResponse(HttpServletResponse.class));
        HttpUtils.initializeUnifiedResponseHeader(response);
        Result<?> result = value instanceof Result ? (Result<?>) value : Result.success(value);
        this.processor.handleReturnValue(result, method, container, request);
    }
}
